package kz.kstu.scantest.business.client.reader.form;

import kz.kstu.scantest.business.client.reader.DataListener;
import kz.kstu.scantest.business.client.reader.com.COMPort;
import org.apache.log4j.Logger;

import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.UnsupportedCommOperationException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.TooManyListenersException;

/**
 * @author Filipp_Stankevich
 *         created: 10.10.11 23:45
 */
public class FormReader {

    private final static Logger LOGGER = Logger.getLogger(COMPort.class);

    public final static int UNKNOWN_ERROR_CODE = 99;
    public final static int CONTROL_POINT_ERROR_CODE = 98;
    public final static int SYNC_TRACK_ERROR_CODE = '2';
    public final static int TIME_OUT_ERROR_CODE = '0';
    public final static int START_DATA_CODE = 52;

    private static final String INITIALIZE_FILE_NAME = "sys/startscan.sys";

    private final static byte[] READ_COMMAND = new byte[]{27, 'R', 'E', 'A', 'D', '#', '1', '0', 13};
    private final static byte[] ERROR_REQUEST = new byte[]{27, 'Q', 'S', 'T', 'S', 13};

    private COMPort comPort;
    private byte[] startData;
    private boolean isInitialized;


    public FormReader(String portName) {
        comPort = new COMPort(portName);
    }

    public void initialize() throws UnsupportedCommOperationException, IOException, PortInUseException,
            NoSuchPortException, TooManyListenersException {
        comPort.initialize();
        isInitialized = true;
    }

    public void read(boolean isNew) throws IOException {
        if (isNew) {
            startRead();
        } else {
            continueRead();
        }
    }

    private void startRead() throws IOException {
        byte[] startData = getStartData();
        comPort.write(startData);
    }

    private void continueRead() throws IOException {
        comPort.write(READ_COMMAND);
        LOGGER.debug("Read command was written.");
    }

    public void requestError() throws IOException {
        comPort.write(ERROR_REQUEST);
        LOGGER.debug("Error request was written.");
    }

    public void shutdown() {
        comPort.shutdown();
        isInitialized = false;
    }

    public boolean isInitialized() {
        return isInitialized;
    }

    public void addDataListener(DataListener dataListener) {
        comPort.addDataListener(dataListener);
    }

    private byte[] getStartData() throws IOException {
        if (startData == null) {
            InputStream fileInputStream = new FileInputStream(INITIALIZE_FILE_NAME);
            startData = new byte[fileInputStream.available()];
            fileInputStream.read(startData);
            fileInputStream.close();
        }
        return startData;
    }

}
